package com.sinog.core.util;

import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class PoiWriteExcel {

    /**
     * @return
     * @author ypc
     * @Description 将poi生成的workbook（工作簿）写成file文件
     */
    public static File createFile(String filePath, String fileName, Workbook workbook) {
        FileOutputStream fileOutputStream = null;
        File exportFile = null;
        //File.separator‌是Java中File类的一个静态字段，用于表示当前操作系统下的文件分隔符。
        // 在不同操作系统中，文件分隔符可能不同，例如在Windows系统中使用反斜杠 \\ 作为文件分隔符，而在Unix/Linux系统中使用斜杠 / 作为文件分隔符。
        // 使用File.separator可以确保代码在不同操作系统上都能正确使用相应的文件分隔符，从而提高代码的可移植性‌
        String exportFilePath = filePath + File.separator + fileName;
        //文件路径白名单检查是一种安全措施，用于确保应用程序只允许访问或操作特定的文件或目录。这种机制通常用于防止未授权的访问或潜在的安全漏洞，
        // 例如路径遍历攻击（Path Traversal Attack），它允许攻击者访问系统上不应该被访问的文件。
        try {
            SecurityWhiteList.checkPath(exportFilePath);
            exportFile= new File(exportFilePath);
            if (!exportFile.getParentFile().exists()) {
                // 父目录不存在，创建父目录
                exportFile.getParentFile().mkdirs();
            }
            //尝试在当前路径下创建一个新的空文件。如果文件不存在，则创建文件并返回true；如果文件已经存在，则不创建新文件并返回false
            exportFile.createNewFile();
            fileOutputStream = new FileOutputStream(exportFilePath);
            workbook.write(fileOutputStream);
            //在使用FileOutputStream时，通常的做法是在数据写入完成后调用flush()方法，以确保所有缓冲的数据都被处理，
            // 然后再调用close()方法关闭流。这样可以最大程度地保证数据的完整性和一致性‌。不调用flush()就直接调用close()，可能会导致部分数据丢失
            fileOutputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != fileOutputStream) {
                try {
                    fileOutputStream.close();
                }catch (IOException e) {
                    System.out.println(e.toString());
                }
            }
            if (null != workbook) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return exportFile;
    }
}